package chaincode

import (
	"encoding/json"

	"github.com/hyperledger/fabric-chaincode-go/shim"
	"github.com/hyperledger/fabric-protos-go/peer"
)

// 资产结构体，包含ID、资产名、资产信息、所有者
type Asset struct {
	ID    string `json:"id"`    // 资产编号
	Name  string `json:"name"`  // 资产名
	Info  string `json:"info"`  // 资产信息
	Owner string `json:"owner"` // 资产所有者
}

// 智能合约结构体
type SmartContract struct{}

// 初始化函数（空实现，仅返回成功）
func (s *SmartContract) Init(stub shim.ChaincodeStubInterface) peer.Response {
	return shim.Success(nil)
}

// 调用入口函数，根据方法名路由
func (s *SmartContract) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
	function, args := stub.GetFunctionAndParameters()
	switch function {
	case "AddAsset": // 创建资产
		return s.AddAsset(stub, args)
	case "TransferAsset": // 转移资产
		return s.TransferAsset(stub, args)
	case "QueryAsset": // 查询资产（用于测试验证）
		return s.QueryAsset(stub, args)
	default:
		return shim.Error("无效的函数名")
	}
}

// 创建资产方法
func (s *SmartContract) AddAsset(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	// 校验参数数量（需包含ID、资产名、资产信息、所有者）
	if len(args) != 4 {
		return shim.Error("参数数量错误，需传入资产ID、资产名、资产信息、所有者")
	}

	// 构建资产对象
	asset := Asset{
		ID:    args[0],
		Name:  args[1],
		Info:  args[2],
		Owner: args[3],
	}

	// 序列化为JSON
	assetJSON, err := json.Marshal(asset)
	if err != nil {
		return shim.Error("资产序列化失败")
	}

	// 存储到账本
	err = stub.PutState(args[0], assetJSON)
	if err != nil {
		return shim.Error("资产存储失败")
	}

	return shim.Success(nil)
}

// 转移资产方法
func (s *SmartContract) TransferAsset(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	// 校验参数数量（需包含资产ID和新所有者）
	if len(args) != 2 {
		return shim.Error("参数数量错误，需传入资产ID和新所有者")
	}

	// 获取资产数据
	assetData, err := stub.GetState(args[0])
	if err != nil || assetData == nil {
		return shim.Error("资产不存在")
	}

	// 反序列化为资产对象
	var asset Asset
	err = json.Unmarshal(assetData, &asset)
	if err != nil {
		return shim.Error("资产反序列化失败")
	}

	// 更新所有者
	asset.Owner = args[1]

	// 序列化并更新账本
	updateJSON, err := json.Marshal(asset)
	if err != nil {
		return shim.Error("更新数据序列化失败")
	}
	err = stub.PutState(args[0], updateJSON)
	if err != nil {
		return shim.Error("资产更新失败")
	}

	return shim.Success(nil)
}

// 查询资产方法（仅用于测试验证）
func (s *SmartContract) QueryAsset(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	if len(args) != 1 {
		return shim.Error("参数数量错误，需传入资产ID")
	}
	assetData, err := stub.GetState(args[0])
	if err != nil || assetData == nil {
		return shim.Error("资产不存在")
	}
	return shim.Success(assetData)
}
